﻿using ArtMath.Flag;
using ArtMath.Resource;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Windows.Forms;

namespace ArtMath.Setting
{
    [Serializable]
    public class UserOptions
    {
        static readonly string UserOptionsSavePath = Application.StartupPath + "\\user.cfg";
        public bool NormalExit;
        /// <summary>
        /// 存储了自动保存时最新文档的路径。Key表示用户保存文档的路径（若没有保存，则为文档HashCode），Value表示系统临时文件夹中最新的副本路径
        /// </summary>
        public Dictionary<string, string> AutoSaveNewestPath;
        public Queue<Tuple<string, string>> RecentDocuments;
        const int MAX = 10;
        public static UserOptions Instance { get; set; }
        static UserOptions()
        {
            IFormatter fmt = new BinaryFormatter();
            try
            {
                Stream stream = new FileStream(UserOptionsSavePath, FileMode.Open, FileAccess.Read, FileShare.None);
                Instance = fmt.Deserialize(stream) as UserOptions;
                stream.Close();
            }
            catch (Exception)
            {
                Instance = new UserOptions();
            }
        }
        UserOptions()
        {
            Reset();
        }
        public void Reset()
        {
            NormalExit = true;
            RecentDocuments = new Queue<Tuple<string, string>>();
            AutoSaveNewestPath = new Dictionary<string, string>();
        }
        public void AddRecentDocument(string docTitle, string docPath)
        {
            RecentDocuments.Enqueue(Tuple.Create(docTitle, docPath));
            while (RecentDocuments.Count > MAX)
            {
                RecentDocuments.Dequeue();
            }
        }
        public void Remove(Tuple<string, string> obj)
        {
            RemoveRecentDocument(obj.Item2);
        }
        public void RemoveRecentDocument(string docPath)
        {
            Tuple<string, string> item;
            int count = 0, sum = RecentDocuments.Count;
            while (count < sum && (item = RecentDocuments.Dequeue()).Item2 != docPath)
            {
                RecentDocuments.Enqueue(item);
                count++;
            }
            while (++count < sum)
            {
                RecentDocuments.Enqueue(RecentDocuments.Dequeue());
            }
        }
        public bool Save()
        {
            return SaveAs(UserOptionsSavePath);
        }
        public bool SaveAs(string path)
        {
            IFormatter fmt = new BinaryFormatter();
            try
            {
                Stream stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
                fmt.Serialize(stream, this);
                stream.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Resources.Translate("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            return true;
        }
    }
}
